package cn.smdq.ch.gateway.core.resource;

import cn.smdq.ch.common.core.config.properties.AuthIgnoreUrlProperties;
import cn.smdq.ch.common.util.ArrayUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;

/**
 * @author shuimodanqing
 * create at:  2019/1/24  8:57 PM
 * @description 服务资源配置
 */
@Configuration
@EnableResourceServer
@EnableConfigurationProperties(AuthIgnoreUrlProperties.class)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter implements ApplicationContextAware {

    private AuthIgnoreUrlProperties properties;

    private ApplicationContext applicationContext;

    @Autowired
    public void setProperties(AuthIgnoreUrlProperties properties) {
        this.properties = properties;
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers(ArrayUtils.toStrArray(properties.getUrls())).permitAll()
                .anyRequest().access("@permissionHandler.hasPermission(authentication,request)");
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.expressionHandler(expressionHandler());
    }

    /**
     * 加密方式
     *
     * @return PasswordEncoder
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public OAuth2WebSecurityExpressionHandler expressionHandler() {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
